/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		auto_array.cpp
 * PURPOSE:		automatic (C++ semantics) object release 
 *				(as opposed to copy and allocation support in heavier containers)
 */

template <class T> void auto_free_default_free(T *x)
{
	delete x;
}

template <class T, void (*free)(T *) = &auto_free_default_free<T> > class auto_free
{
	T *ptr;

	void free_if()
	{
		if(ptr)
			free(ptr);

		ptr = 0;
	}
public:
	auto_free() :
	  ptr(0)
	{}
	auto_free(auto_take<T> ptr) :
		ptr(ptr.ptr)
	{}
	auto_free(auto_free const &x)
	{
		struct ERROR;
		ERROR Error;
		//no copy operation
	}
	T *release_unsafe()
	{
		T *ret = ptr;
		ptr = 0;
		return ret;
	}
	auto_take<T> release()
	{
		T *ret = ptr;
		ptr = 0;
		return auto_take<T>(ret);
	}
	void reset()
	{
		free_if();
	}
	void set(T *x)
	{
		free_if();
		ptr = x;
	}
	operator T const *() const
	{
		return ptr;
	}
	T const *operator->() const
	{
		return ptr;
	}
	T *get()
	{
		return ptr;
	}
	operator T *()
	{
		return ptr;
	}
	T *operator->()
	{
		return ptr;
	}
	T **assign_indirect()
	{
		free_if();
		return &ptr;
	}
	auto_free &operator =(auto_take<T> x)
	{
		free_if();
		ptr = x.ptr;
		return *this;
	}
	auto_free &operator =(auto_free const &x)
	{
		struct ERROR;
		ERROR Error;
		//no auto assignment
	}
	~auto_free()
	{
		free_if();
	}
};